package com.woniuxy.user.controller;


import cn.hutool.core.bean.BeanUtil;
import com.woniu.zsd.commons.core.model.Result;
import com.woniuxy.user.entity.UserInfo;
import com.woniuxy.user.form.*;
import com.woniuxy.user.param.*;
import com.woniuxy.user.service.IUserInfoService;
import com.woniuxy.user.service.IUserLogService;
import com.woniuxy.user.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * <p>
 * 用户详情表 前端控制器
 * </p>
 *
 * @author author
 * @since 2025-05-13
 */
@RestController
@RequestMapping("/user-info")
@Api(tags = "用户详情管理")
public class UserInfoController {

    @Resource
    private IUserInfoService iUserInfoService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private IUserLogService userLogService;

    /**
     * 用户账号密码登录接口
     */
    @PostMapping("/userPsswordLogin")
    @ApiOperation("用户账号登录接口")
    public Result<String> login(@RequestBody UserPasswordLoginForm upl, HttpServletResponse resp ) throws Exception{
        UserInfo userInfo=  iUserInfoService.userPsswordLogin(BeanUtil.toBean(upl, UserPasswordLoginParam.class));
        //生成JWT令牌
        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(userInfo);

        //短token
        String accessToken = JwtUtils.createToken(stringObjectMap, 5);
        //长token
        String refreshToken = JwtUtils.createToken(stringObjectMap, 24 * 60);
        //通过响应头将jwt响应给客户端
        resp.setHeader("token", accessToken);
        //在跨域请求访问时 必须公开该请求头 前端才能获取到
        resp.setHeader("Access-Control-Expose-Headers", "token");
        //保存长到redis
        stringRedisTemplate.opsForValue().set(accessToken, refreshToken, 24 * 60, TimeUnit.MINUTES);
        //保存短到redis
        stringRedisTemplate.opsForValue().set("token:expire" + accessToken, "", 5, TimeUnit.MINUTES);

        // 记录登录日志
        userLogService.logUserAction(Integer.parseInt(stringObjectMap.get("id").toString()), userInfo.getLoginName(), "LOGIN", "用户登录", 1, null);

        return new Result<String>().setMsg("账号密码登录成功").setCode(200);
    }




    /**
     * 用户注册
     */
    @PostMapping("/userRegister")
    @ApiOperation("用户注册接口")
    public Result<String> register(@RequestBody AddUserinfoForm form) throws Exception{
        iUserInfoService.register(form);

        return new Result<String>().setMsg("注册成功").setCode(200);
    }

    /**
     * 用户注册发送验证码
     */
    @PostMapping("/userRegisterCode")
    @ApiOperation("用户注册发送验证码接口")
    public Result<String> registerCode(@RequestParam String phone) throws Exception{
        iUserInfoService.registerCode(phone);

        return new Result<String>().setMsg("注册验证码发送成功").setCode(200);
    }

    /**
     * 用户登录发送验证码接口
     */
    @PostMapping("/userLoginCode")
    @ApiOperation("用户发送登录验证码")
    public Result<String> loginCode(@RequestParam String phone) throws Exception{
        iUserInfoService.loginCode(phone);
        return new Result<String>().setMsg("发送成功").setCode(200);
    }



    /**
     * 用户登录发送验证码
     */
    @PostMapping("/userLoginCodePhone")
    @ApiOperation("验证码登录")
    public Result<String> loginCode(@RequestBody UserLoginCodeForm form, HttpServletResponse response) throws Exception{
         UserInfo userInfo  = iUserInfoService.loginCodePhone(BeanUtil.toBean(form, UserLoginCodeParam.class));
        //生成JWT令牌
        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(userInfo);

        //短token
        String accessToken = JwtUtils.createToken(stringObjectMap, 5);
        //长token
        String refreshToken = JwtUtils.createToken(stringObjectMap, 24 * 60);
        //保存长到redis
        stringRedisTemplate.opsForValue().set(accessToken, refreshToken, 24 * 60, TimeUnit.MINUTES);
        //保存短到redis
        stringRedisTemplate.opsForValue().set("token:expire" + accessToken, "", 5, TimeUnit.MINUTES);
        //通过响应头将jwt响应给客户端
        response.setHeader("token", accessToken);
        //在跨域请求访问时 必须公开该请求头 前端才能获取到
        response.setHeader("Access-Control-Expose-Headers", "token");
        return new Result<String>().setMsg("登录成功").setCode(200);
    }

    /**
     * 用户查看自己详情
     */
    @GetMapping("/userInfo")
    @ApiOperation("用户查看基本信息")
    public Result<UserInfoForm> userInfo(@RequestHeader("token") String token) throws Exception {
        // 从token中拿到id
        String id = JwtUtils.parseToken(token).get("id").toString();
        UserInfoForm userInfoForm = iUserInfoService.userInfo(Integer.parseInt(id));
        return new Result<UserInfoForm>().setData(userInfoForm).setCode(200).setMsg("查询个人信息成功");
    }

    /**
     * 用户修改密码
     */
    @PutMapping("/userUpdatePassword")
    @ApiOperation("用户修改密码接口")
    public Result<String> userUpdatePassword(@RequestBody UpdatePasswordForm form, @RequestHeader("token") String token) throws Exception {
        iUserInfoService.updatePassword(BeanUtil.toBean(form, UpdatePasswordParam.class),token);

        return new Result<String>().setCode(200).setMsg( "修改密码成功");
    }

    /**
     * 修改用户的头像
     */
    @PostMapping("/updatePhoto")
    @ApiOperation("修改用户的头像")
    public Result<String> updatePhoto(@RequestHeader("token") String token,  MultipartFile photo) throws Exception {
        // 从token中拿到id
        String id = JwtUtils.parseToken(token).get("id").toString();
        // 处理文件上传逻辑
        iUserInfoService.updatePhoto(photo, Integer.parseInt(id));
        return new Result<String>().setMsg("上传成功").setCode(200);
    }

    /**
     * 用户修改登录账号
     */
    @PutMapping("/userUpdateLoginName")
    @ApiOperation("用户修改登录账号")
    public Result<String> userUpdateLoginName(@RequestBody UpdateLoginNameForm form, @RequestHeader("token") String token) throws Exception {

        iUserInfoService.updateLoginName(BeanUtil.toBean(form, UpdateLoginNameParam.class),token);
        return new Result<String>().setMsg("修改登录账号成功").setCode(200);
    }



    /**
     * 用户修改昵称
     */
    @PutMapping("/userUpdateNickName")
    @ApiOperation("用户修改昵称")
    public Result<String> userUpdateNickName( @RequestHeader("token") String token,String nickName) throws Exception {
        // 从token中拿到id
        String id = JwtUtils.parseToken(token).get("id").toString();

        iUserInfoService.updateNickName(id,nickName);
        return new Result<String>().setMsg("修改成功").setCode(200);
    }

    /**
     * 用户发送换绑手机号验证码
     */
    @PostMapping("/userUpdatePhoneCode")
    @ApiOperation("用户发送换绑手机号验证码")
    public Result<String> userUpdatePhoneCode(@RequestParam String phone) throws Exception {
        iUserInfoService.changeBindingSendCode(phone);
        return new Result<String>().setMsg("发送成功").setCode(200);
    }

        /**
     * 用户修改手机号
     */
    @PutMapping("/userUpdatePhone")
    @ApiOperation("用户修改手机号")
    public Result<String> userUpdatePhone(@RequestBody UpdatePhoneForm form, @RequestHeader("token") String token) throws Exception {


        iUserInfoService.updatePhone(BeanUtil.toBean(form, UpdatePhoneParam.class),token);
        return new Result<String>().setMsg("修改成功").setCode(200);
    }

    /**
     * 用户修改密码（验证码形式）发送验证码
     */
    @PostMapping("/userUpdatePasswordCode")
    @ApiOperation("用户修改密码（验证码形式）发送验证码")
    public Result<String> userUpdatePasswordCode(@RequestParam String phone ,@RequestHeader("token") String token) throws Exception {
        iUserInfoService.updatePasswordCode(phone,token);
        return new Result<String>().setMsg("发送成功").setCode(200);
    }

    /**
     * 用户修改密码（验证码形式）
     */
    @PostMapping("/userUpdatePasswordCodeX")
    @ApiOperation("用户修改密码（验证码形式）")
    public Result<String> userUpdatePasswordCode(@RequestBody UpdatePasswordCodeForm form,@RequestHeader("token") String token) throws Exception {
        iUserInfoService.updatePasswordCodeX(BeanUtil.toBean(form, UpdatePasswordCodeParam.class), token);
        return new Result<String>().setMsg("修改成功").setCode(200);
    }




}
